/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.core.action.retrieve;

import com.inspur.edp.bef.api.be.IBEContext;
import com.inspur.edp.bef.api.parameter.retrieve.RetrieveParam;
import com.inspur.edp.bef.core.be.CoreBEContext;
import com.inspur.edp.bef.core.lock.LockService;
import com.inspur.edp.bef.core.lock.LockUtils;
import com.inspur.edp.bef.core.scope.ScopeNodeParameter;
import com.inspur.edp.bef.core.scope.SingleBETypeExtension;
import com.inspur.edp.cef.api.repository.IRootRepository;
import com.inspur.edp.cef.api.scope.ICefScopeNodeParameter;
import com.inspur.edp.cef.entity.condition.RetrieveFilter;
import com.inspur.edp.cef.entity.entity.IEntityData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

public class CheckVersionExtension extends SingleBETypeExtension<CheckVersionScopeNodeParameter> {

	public CheckVersionExtension() {
		super();
	}

	@Override
	public void onExtendSetComplete() {
		IBEContext context=null;
		if(getParameters()!=null&&getParameters().size()>0)
			context=((ScopeNodeParameter)getParameters().get(0)).getBEContext();
		//〇 批量加锁:
		if(LockUtils.needLock(context.getModelResInfo()))
			LockService.getInstance().addLocks(getCurrentBeType(), getNeedLockIds());
		//① 批量校验；
		List<String> checkVersionResult = multiCheckVersion();
		//② 构造版本校验不通过的idList，到DAL取；
		List<IEntityData> dicData = multiRetrieveFromDAL(checkVersionResult);
		//③ 执行回调函数；
		executeAction(dicData);
	}

	private List<String> getNeedLockIds() {
		List<String> needLockParas = new ArrayList<>();
		for (CheckVersionScopeNodeParameter item : getBEParameters()) {
			if (item.getParam().getNeedLock()) {
				needLockParas.add(item.getBEContext().getID());
			}
		}
		return needLockParas;
	}

	/**
	 * 版本校验不通过的执行回调函数
	 *
	 * @param dicData Retrieve结果
	 */
	private void executeAction(List<IEntityData> dicData) {
		if (dicData == null || dicData.isEmpty()) {
			return;
		}
		for (IEntityData item : dicData) {
			for (ICefScopeNodeParameter para : getParameters()) {
				CoreBEContext context = (CoreBEContext) ((CheckVersionScopeNodeParameter) para).getBEContext();
				if (context.getID().equals(item.getID())) {
					context.clearData();
					((CheckVersionScopeNodeParameter) para).executeAction(context, item);
				}
			}
		}
	}

	private List<String> multiCheckVersion() {
		List<String> idList = getBEParameters().stream().map(a -> a.getBEContext().getID()).collect(Collectors.toList());
		IRootRepository repository = getSessionItem().getBEManager().getRepository();
		HashMap<String, Date> versionDic = repository.getVersionControlValues(idList);
		List<String> list = new ArrayList<>();
		for (ScopeNodeParameter par : getBEParameters()) {
			String id = par.getBEContext().getID();
			Date currentVersion = new Date(0);
			if (versionDic.containsKey(id)) {
				currentVersion = versionDic.get(id);
			} else {
				list.add(id);
			}
			boolean result = (currentVersion.compareTo(new Date(0)) != 0)
					&& (par.getBEContext().getBizEntity().getVersionControlPropValue() != null && currentVersion.compareTo(par.getBEContext().getBizEntity().getVersionControlPropValue()) == 0);
			if (!result) {
				list.add(id);
			}
		}
		return list;
	}

	private List<IEntityData> multiRetrieveFromDAL(List<String> checkVersionResult) {
		if (checkVersionResult.size() == 0) {
			return null;
		}
		getRetrieveFilter();
		IRootRepository repository = getSessionItem().getBEManager().getRepository();
		RetrieveFilter rf = getRetrieveFilter();
		try {
			return rf != null ? repository.retrieve(checkVersionResult, rf)
					: repository.retrieve(checkVersionResult);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	private RetrieveFilter getRetrieveFilter() {
		RetrieveParam rp = getBEParameters().get(0).getParam();
		return rp != null ? rp.getRetrieveFilter() : null;
	}
}
